package jp.androidgroup.chiba.androidresearch.db;

import java.util.ArrayList;
import java.util.List;

import jp.androidgroup.chiba.androidresearch.Common;
import jp.androidgroup.chiba.androidresearch.data.*;


import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper{
	  /* データベース名 */
    private final static String DB_NAME = "androidresearchdb";
    /* データベースのバージョン */
    private final static int DB_VER = 1;

	public DatabaseHelper(Context context) {
		super(context, DB_NAME, null, DB_VER);
	}

	/*
	 * データベース作成
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
	 */
	public void onCreate(SQLiteDatabase db) {

		Base tables[] = new Base[]{new Counter(), new Occupation(), new Place(), new Time(), new Use()};

		db.beginTransaction();
		try {
			String query;
			// SQLiteStatement stmt;

			// テーブルを作成する
			for(int i = 0;i < tables.length;i++){
				query = "create table " + tables[i].getClass().getSimpleName() + "(";
				query += "Id text primary key,";
				for(int k = 0;k < tables[i].getColumns().length;k++){
					query += tables[i].getColumns()[k] + " text";
					if(k + 1 < tables[i].getColumns().length){
						query += ",";
					}
				}
				query += ")";
				db.execSQL(query);
			}

			db.setTransactionSuccessful();
		} finally {
			db.endTransaction();
		}
	}

	/*
	 * データベースアップグレード
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}

	/**
	 * データの削除
	 * @param db
	 * @param data
	 * @throws Exception
	 */
	public void delete(SQLiteDatabase db, Base data) throws Exception{
		// 削除する
		db.execSQL("delete from " + data.getClass().getSimpleName() + " where Id = '" + data.getId() + "'");
	}

	/**
	 * データの挿入/更新
	 * @param data
	 * @throws Exception
	 */
	public void save(SQLiteDatabase db, Base data) throws Exception{
		String sql;
		Object value;
		String values;

		// 一度削除する
		delete(db, data);

		// データを挿入する
		sql = "insert into " + data.getClass().getSimpleName() + "(Id,";
		values = "'" + data.getId() + "',";
		for(int i = 0;i < data.getColumns().length;i++){
			sql += data.getColumns()[i] + ",";
			value = Common.getFieldValueByName(data, data.getColumns()[i]);
			values += "'" + (value == null?"":value) + "',";
		}
		// 最後,の場合に削除する
		if(sql.indexOf(",",sql.length() - 1) > 0){
			sql = sql.substring(0, sql.length() - 1);
		}
		if(values.indexOf(",",values.length() - 1) > 0){
			values = values.substring(0, values.length() - 1);
		}
		sql += ")values(" + values + ");";

		db.execSQL(sql);
	}

	/**
	 * IDによる検索
	 *
	 * @param db データベースコネクション
	 * @param id 検索するID
	 * @param cls 検索結果を登録するBaseクラス型
	 * @return　結果を登録したBaseクラス
	 * @throws Exception
	 */
	public Base findById(SQLiteDatabase db, String id, Class<?> cls) throws Exception{
		Cursor c;
		Base data;

		data = null;
		if(cls.getSuperclass().equals(Base.class)){
			// IDでクエリー送信
			c = db.query(cls.getSimpleName(), null, "Id='" + id + "'", null, null, null, null);
			// 1件以上ある場合は、Pojoにデータをセット
			if(c.getCount() == 1){
				data = (Base) cls.newInstance();
				c.moveToFirst();
				data.setId(id);
				for(int i = 0;i < data.getColumns().length;i++){
					Common.setFieldValueByName(data, data.getColumns()[i], c.getString(c.getColumnIndex(data.getColumns()[i])));
				}
			}
			c.close();
		}

		return data;
	}

	/**
	 * クエリー送信
	 *
	 * @param db データベース
	 * @param cls　検索結果を登録するBaseクラス型
	 * @param selection　where句
	 * @param order ソート条件
	 * @return　結果を登録したBaseクラス配列
	 * @throws Exception
	 */
	public List<?> find(SQLiteDatabase db,Class<?> cls, String[] columns, String selection, String orderby) throws Exception{

		return find(db, cls, columns, selection, null, null, orderby, null);

	}

	/**
	 * クエリー送信
	 *
	 * @param db データベース
	 * @param cls　検索結果を登録するBaseクラス型
	 * @param selection　where句
	 * @param order ソート条件
	 * @return　結果を登録したBaseクラス配列
	 * @throws Exception
	 */
	public List<?> find(SQLiteDatabase db,Class<?> cls, String[] columns, String selection, String groupby, String having, String orderby, String limit) throws Exception{
		Cursor c;
		Base data;
		ArrayList<Object> datalist;

		datalist = new ArrayList<Object>();
		if(cls.getSuperclass().equals(Base.class)){
			// IDでクエリー送信
			c = db.query(cls.getSimpleName(), columns, selection, null, groupby, having, orderby, limit);
			c.moveToFirst();
			// 1件以上ある場合は、Pojoにデータをセット
			if(c.getCount() > 0){
				for(int i = 0;i < c.getCount();i++){
					data = (Base) cls.newInstance();
					for(int k = 0;k < c.getColumnCount();k++){
						Common.setFieldValueByName(data, c.getColumnName(k), c.getString(k));
					}
					c.moveToNext();

					datalist.add(data);
				}
			}
			c.close();
		}

		return datalist;
	}
}
